import os
import sys
import hashlib
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout,
                             QHBoxLayout, QPushButton, QTreeWidget, QTreeWidgetItem,
                             QFileDialog, QProgressDialog, QLabel, QMessageBox,
                             QScrollArea, QGridLayout, QCheckBox, QSplitter,
                             QMenuBar, QAction, QStatusBar)
from PyQt5.QtGui import QPixmap, QImage, QPalette, QColor, QFont
from PyQt5.QtCore import Qt, QThread, pyqtSignal


class ResourceHandler:
    """资源文件处理工具类，兼容开发环境和打包环境"""

    @staticmethod
    def get_resource_path(relative_path):
        """
        获取资源文件的绝对路径
        :param relative_path: 相对于resources文件夹的路径，例如"bg.png"
        :return: 资源文件的绝对路径
        """
        try:
            # 打包后环境，获取临时目录路径
            base_path = sys._MEIPASS
        except Exception:
            # 开发环境，使用当前文件所在目录
            base_path = os.path.dirname(os.path.abspath(__file__))

        # 构建完整资源路径
        return os.path.join(base_path, 'resources', relative_path)


class ImageScanner(QThread):
    """图片扫描线程，负责在后台扫描指定目录的图片文件"""
    progress_updated = pyqtSignal(int)
    scan_finished = pyqtSignal(dict, int, int)
    file_processed = pyqtSignal(str)  # 新增信号：发送当前处理的文件名

    def __init__(self, root_dirs):
        super().__init__()
        self.root_dirs = root_dirs
        self.stop_scan = False

    def run(self):
        # 存储图片信息：键为文件大小，值为该大小的文件路径列表
        image_files = {}

        # 常见图片文件扩展名
        image_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.webp',
                            '.jfif', '.pjpeg', '.pjp', '.svg', '.ico', '.heic', '.raw'}

        # 先计算总文件数，用于进度显示
        total_files = 0
        for root_dir in self.root_dirs:
            for dirpath, _, filenames in os.walk(root_dir):
                if self.stop_scan:
                    return
                for filename in filenames:
                    ext = os.path.splitext(filename)[1].lower()
                    if ext in image_extensions:
                        total_files += 1

        processed_files = 0

        # 再次遍历，收集图片文件信息
        for root_dir in self.root_dirs:
            for dirpath, _, filenames in os.walk(root_dir):
                if self.stop_scan:
                    return
                for filename in filenames:
                    ext = os.path.splitext(filename)[1].lower()
                    if ext in image_extensions:
                        file_path = os.path.join(dirpath, filename)
                        try:
                            # 发送当前处理的文件名
                            self.file_processed.emit(os.path.basename(file_path))

                            # 获取文件大小
                            file_size = os.path.getsize(file_path)

                            # 按文件大小分组
                            if file_size not in image_files:
                                image_files[file_size] = []
                            image_files[file_size].append(file_path)

                            processed_files += 1
                            progress = int((processed_files / total_files) * 100)
                            self.progress_updated.emit(progress)
                        except Exception as e:
                            print(f"处理文件 {file_path} 时出错: {e}")

        # 过滤掉只有一个文件的组（没有重复）
        duplicate_candidates = {size: paths for size, paths in image_files.items() if len(paths) > 1}

        # 对候选文件进行内容哈希比较，找出真正相同的文件
        duplicates = {}
        group_id = 1
        total_duplicate_files = 0

        for size, paths in duplicate_candidates.items():
            if self.stop_scan:
                return

            # 使用字典存储相同哈希的文件路径
            hash_groups = {}

            for path in paths:
                try:
                    # 发送当前处理的文件名
                    self.file_processed.emit(os.path.basename(path))

                    # 计算文件内容的MD5哈希
                    file_hash = self.calculate_file_hash(path)

                    if file_hash not in hash_groups:
                        hash_groups[file_hash] = []
                    hash_groups[file_hash].append(path)
                except Exception as e:
                    print(f"计算文件 {path} 的哈希时出错: {e}")

            # 将哈希相同的文件组添加到结果中
            for hash_val, group_paths in hash_groups.items():
                if len(group_paths) > 1:
                    duplicates[group_id] = group_paths
                    total_duplicate_files += len(group_paths)
                    group_id += 1

        # 发送扫描完成信号，包含重复文件信息、总处理文件数和重复文件数
        self.scan_finished.emit(duplicates, processed_files, total_duplicate_files)

    def calculate_file_hash(self, file_path, block_size=65536):
        """计算文件的MD5哈希值"""
        hasher = hashlib.md5()
        with open(file_path, 'rb') as f:
            buf = f.read(block_size)
            while buf:
                if self.stop_scan:
                    return None
                hasher.update(buf)
                buf = f.read(block_size)
        return hasher.hexdigest()

    def stop(self):
        """停止扫描线程"""
        self.stop_scan = True
        self.wait()


class ImagePreview(QWidget):
    """图片预览组件"""

    def __init__(self, parent=None):
        super().__init__(parent)
        self.init_ui()
        self.load_default_image()

    def init_ui(self):
        layout = QVBoxLayout(self)

        # 设置背景颜色为浅灰色
        self.setStyleSheet("background-color: #f0f7ff;")

        # 预览标题
        self.title_label = QLabel("选择图片进行预览")
        self.title_label.setAlignment(Qt.AlignCenter)
        self.title_label.setStyleSheet("font-size: 16px; font-weight: bold; color: #1a5276; margin: 10px 0;")
        layout.addWidget(self.title_label)

        # 图片预览区域
        self.scroll_area = QScrollArea()
        self.scroll_area.setWidgetResizable(True)
        self.scroll_area.setStyleSheet("background-color: white; border: 1px solid #b3d1ff; border-radius: 4px;")

        self.preview_widget = QWidget()
        self.preview_layout = QVBoxLayout(self.preview_widget)
        self.preview_layout.setAlignment(Qt.AlignCenter)
        self.scroll_area.setWidget(self.preview_widget)
        layout.addWidget(self.scroll_area)

        # 文件路径显示
        self.path_label = QLabel("")
        self.path_label.setWordWrap(True)
        self.path_label.setStyleSheet("color: #34495e; padding: 10px;")
        layout.addWidget(self.path_label)

        self.setLayout(layout)

    def load_default_image(self):
        """加载默认图片，使用资源处理器获取正确路径"""
        # 使用ResourceHandler获取正确的资源路径
        default_path = ResourceHandler.get_resource_path('bg.png')

        # 添加调试信息，帮助排查问题
        print(f"尝试加载默认图片: {default_path}")

        if os.path.exists(default_path):
            try:
                img_label = QLabel()
                pixmap = QPixmap(default_path)

                # 缩放图片以适应预览区域，但保持比例
                scaled_pixmap = pixmap.scaled(
                    600, 600,
                    Qt.KeepAspectRatio,
                    Qt.SmoothTransformation
                )
                img_label.setPixmap(scaled_pixmap)
                img_label.setAlignment(Qt.AlignCenter)
                self.preview_layout.addWidget(img_label)

                self.title_label.setText("重复图片清理工具")
                self.path_label.setText("请选择目录并开始扫描以查找重复图片")
                print(f"成功加载默认图片: {default_path}")
            except Exception as e:
                error_label = QLabel(f"无法加载默认图片: {str(e)}")
                error_label.setAlignment(Qt.AlignCenter)
                error_label.setStyleSheet("color: #e74c3c; margin: 20px;")
                self.preview_layout.addWidget(error_label)
                print(f"加载默认图片失败: {str(e)}")
        else:
            info_label = QLabel(f"默认图片未找到: {default_path}\n请选择图片进行预览")
            info_label.setAlignment(Qt.AlignCenter)
            info_label.setStyleSheet("color: #7f8c8d; margin: 20px;")
            self.preview_layout.addWidget(info_label)
            print(f"默认图片不存在: {default_path}")

    def set_image(self, image_paths):
        """设置要预览的图片"""
        # 清空现有内容
        while self.preview_layout.count():
            item = self.preview_layout.takeAt(0)
            widget = item.widget()
            if widget:
                widget.deleteLater()

        if not image_paths:
            self.title_label.setText("未选择图片")
            self.path_label.setText("")
            return

        self.title_label.setText(f"预览 {len(image_paths)} 张图片")

        # 显示所有选中的图片
        for path in image_paths:
            try:
                # 创建图片标签
                img_label = QLabel()
                pixmap = QPixmap(path)

                # 缩放图片以适应预览区域，但保持比例
                scaled_pixmap = pixmap.scaled(
                    600, 600,
                    Qt.KeepAspectRatio,
                    Qt.SmoothTransformation
                )
                img_label.setPixmap(scaled_pixmap)
                img_label.setAlignment(Qt.AlignCenter)

                # 添加图片和路径标签
                self.preview_layout.addWidget(img_label)

                path_label = QLabel(f"路径: {path}")
                path_label.setWordWrap(True)
                path_label.setStyleSheet("color: #34495e; margin: 5px 0;")
                self.preview_layout.addWidget(path_label)

                # 添加分隔线
                separator = QLabel("----------------------------------------")
                separator.setAlignment(Qt.AlignCenter)
                separator.setStyleSheet("color: #bdc3c7; margin: 10px 0;")
                self.preview_layout.addWidget(separator)

            except Exception as e:
                error_label = QLabel(f"无法预览图片: {path}\n错误: {str(e)}")
                error_label.setWordWrap(True)
                error_label.setStyleSheet("color: #e74c3c; margin: 10px 0;")
                self.preview_layout.addWidget(error_label)


class DuplicateImageFinder(QMainWindow):
    """主窗口类"""

    def __init__(self):
        super().__init__()
        self.duplicates = {}  # 存储重复图片组
        self.selected_dirs = []  # 存储选择的目录
        self.init_ui()

    def init_ui(self):
        """初始化UI界面"""
        self.setWindowTitle("人人刚需必备，图片照片冗余去除工具。尽情分享，完全免费！")
        self.setGeometry(100, 100, 1200, 800)

        # 设置主窗口背景色
        self.setStyleSheet("background-color: #f8f9fa;")

        # 创建菜单栏
        menubar = self.menuBar()
        menubar.setStyleSheet("background-color: #e6f2ff; padding: 5px;")

        # 添加关于按钮
        about_action = QAction("关于", self)
        about_action.triggered.connect(self.show_about_dialog)
        menubar.addAction(about_action)

        # 创建主部件和布局
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        main_layout = QVBoxLayout(central_widget)

        # 顶部按钮区域
        button_layout = QHBoxLayout()
        button_layout.setContentsMargins(10, 10, 10, 10)
        button_layout.setSpacing(10)

        # 按钮样式表
        button_style = """
            QPushButton {
                background-color: #3498db;
                color: white;
                border-radius: 4px;
                padding: 8px 16px;
                font-size: 14px;
                border: none;
            }
            QPushButton:hover {
                background-color: #2980b9;
            }
            QPushButton:disabled {
                background-color: #bdc3c7;
                color: #7f8c8d;
            }
        """

        # 删除按钮使用红色系
        delete_button_style = """
            QPushButton {
                background-color: #e74c3c;
                color: white;
                border-radius: 4px;
                padding: 8px 16px;
                font-size: 14px;
                border: none;
            }
            QPushButton:hover {
                background-color: #c0392b;
            }
            QPushButton:disabled {
                background-color: #bdc3c7;
                color: #7f8c8d;
            }
        """

        # 一键选择按钮使用绿色系
        select_button_style = """
            QPushButton {
                background-color: #2ecc71;
                color: white;
                border-radius: 4px;
                padding: 8px 16px;
                font-size: 14px;
                border: none;
            }
            QPushButton:hover {
                background-color: #27ae60;
            }
            QPushButton:disabled {
                background-color: #bdc3c7;
                color: #7f8c8d;
            }
        """

        self.select_dir_btn = QPushButton("选择目录")
        self.select_dir_btn.clicked.connect(self.select_directories)
        self.select_dir_btn.setStyleSheet(button_style)
        button_layout.addWidget(self.select_dir_btn)

        self.scan_btn = QPushButton("开始扫描")
        self.scan_btn.clicked.connect(self.start_scan)
        self.scan_btn.setEnabled(False)
        self.scan_btn.setStyleSheet(button_style)
        button_layout.addWidget(self.scan_btn)

        # 一键选择按钮
        self.one_click_select_btn = QPushButton("一键选择（每组保留一个）")
        self.one_click_select_btn.clicked.connect(self.one_click_select)
        self.one_click_select_btn.setEnabled(False)
        self.one_click_select_btn.setStyleSheet(select_button_style)
        button_layout.addWidget(self.one_click_select_btn)

        self.delete_btn = QPushButton("删除选中的图片(删了就没了)")
        self.delete_btn.clicked.connect(self.delete_selected)
        self.delete_btn.setEnabled(False)
        self.delete_btn.setStyleSheet(delete_button_style)
        button_layout.addWidget(self.delete_btn)

        button_layout.addStretch()
        main_layout.addLayout(button_layout)

        # 中间内容区域（分割为列表和预览）
        splitter = QSplitter(Qt.Horizontal)
        splitter.setStyleSheet("background-color: #e6f2ff;")

        # 重复文件列表
        self.duplicates_tree = QTreeWidget()
        self.duplicates_tree.setHeaderLabels(["重复组", "文件路径", "大小"])
        self.duplicates_tree.itemSelectionChanged.connect(self.on_item_selected)
        # 设置树状视图样式
        self.duplicates_tree.setStyleSheet("""
            QTreeWidget {
                background-color: white;
                border: 1px solid #b3d1ff;
                border-radius: 4px;
                padding: 5px;
            }
            QTreeWidget::item {
                height: 25px;
                border-bottom: 1px solid #f0f0f0;
            }
            QTreeWidget::item:selected {
                background-color: #d6eaf8;
                color: #1a5276;
            }
            QHeaderView::section {
                background-color: #e6f2ff;
                color: #34495e;
                padding: 8px;
                border: 1px solid #b3d1ff;
                font-weight: bold;
            }
        """)
        splitter.addWidget(self.duplicates_tree)

        # 图片预览区域
        self.image_preview = ImagePreview()
        splitter.addWidget(self.image_preview)

        # 设置分割器的初始大小
        splitter.setSizes([500, 700])

        main_layout.addWidget(splitter)

        # 底部状态栏
        self.statusBar().setStyleSheet("background-color: #e6f2ff; color: #34495e; padding: 5px;")
        self.statusBar().showMessage("就绪")

    def select_directories(self):
        """选择要扫描的目录"""
        dir_path = QFileDialog.getExistingDirectory(
            self, "选择要扫描的目录", os.path.expanduser("~"),
            QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks
        )

        if dir_path:
            # 检查是否是C盘
            if dir_path.lower().startswith("c:"):
                QMessageBox.warning(
                    self, "警告",
                    "C盘不能进行搜索和清理。\n如果清理微信，建议将微信文件迁移到D盘后再进行处理。"
                )
                return

            # 保存绝对路径
            self.selected_dirs = [os.path.abspath(dir_path)]
            self.statusBar().showMessage(f"已选择目录: {self.selected_dirs[0]}")
            self.scan_btn.setEnabled(True)

    def start_scan(self):
        """开始扫描图片"""
        if not self.selected_dirs:
            QMessageBox.warning(self, "警告", "请先选择要扫描的目录")
            return

        # 再次检查是否是C盘（防止通过其他方式选择C盘）
        if any(dir_path.lower().startswith("c:") for dir_path in self.selected_dirs):
            QMessageBox.warning(
                self, "警告",
                "C盘不能进行搜索和清理。\n如果清理微信，建议将微信文件迁移到D盘后再进行处理。"
            )
            return

        # 清空之前的结果
        self.duplicates_tree.clear()
        self.duplicates = {}

        # 禁用相关按钮
        self.one_click_select_btn.setEnabled(False)
        self.delete_btn.setEnabled(False)
        self.select_dir_btn.setEnabled(False)
        self.scan_btn.setEnabled(False)

        # 创建进度对话框
        self.progress_dialog = QProgressDialog("正在扫描图片...", "取消", 0, 100, self)
        self.progress_dialog.setWindowTitle("扫描中")
        self.progress_dialog.setWindowModality(Qt.WindowModal)
        self.progress_dialog.setStyleSheet("""
            QProgressDialog {
                background-color: white;
                border: 1px solid #b3d1ff;
                border-radius: 4px;
            }
            QProgressBar {
                background-color: #f0f7ff;
                border: 1px solid #b3d1ff;
                border-radius: 3px;
                text-align: center;
                height: 15px;
            }
            QProgressBar::chunk {
                background-color: #3498db;
                border-radius: 2px;
            }
        """)
        self.progress_dialog.canceled.connect(self.cancel_scan)

        # 创建并启动扫描线程
        self.scanner = ImageScanner(self.selected_dirs)
        self.scanner.progress_updated.connect(self.update_progress)
        self.scanner.scan_finished.connect(self.on_scan_finished)
        self.scanner.file_processed.connect(self.update_status_with_filename)  # 连接文件名更新信号
        self.scanner.start()

        self.statusBar().showMessage(f"正在扫描目录: {self.selected_dirs[0]}")

    def update_progress(self, value):
        """更新扫描进度"""
        self.progress_dialog.setValue(value)

    def update_status_with_filename(self, filename):
        """更新状态栏，显示当前正在处理的文件名"""
        if self.selected_dirs:
            self.statusBar().showMessage(f"目录: {self.selected_dirs[0]} >>正在处理: {filename} ")
        else:
            self.statusBar().showMessage(f"正在处理: {filename}")

    def cancel_scan(self):
        """取消扫描"""
        if hasattr(self, 'scanner') and self.scanner.isRunning():
            self.scanner.stop()
        self.statusBar().showMessage("扫描已取消")
        self.scan_btn.setEnabled(True)
        self.select_dir_btn.setEnabled(True)

    def on_scan_finished(self, duplicates, total_files, total_duplicates):
        """扫描完成后的处理"""
        self.progress_dialog.close()
        self.duplicates = duplicates

        # 显示扫描结果
        if not duplicates:
            QMessageBox.information(self, "结果", "未发现重复的图片")
            self.statusBar().showMessage(
                f"扫描完成 | 共处理 {total_files} 个文件 | 未发现重复图片 | 目录: {self.selected_dirs[0]}")
        else:
            self.display_duplicates()
            self.statusBar().showMessage(
                f"扫描完成 | 共处理 {total_files} 个文件 | 发现 {len(duplicates)} 组重复图片，共 {total_duplicates} 张 | 目录: {self.selected_dirs[0]}"
            )
            self.delete_btn.setEnabled(True)
            self.one_click_select_btn.setEnabled(True)  # 扫描完成后启用一键选择按钮

        self.scan_btn.setEnabled(True)
        self.select_dir_btn.setEnabled(True)

    def display_duplicates(self):
        """在树形视图中显示重复图片组"""
        for group_id, paths in self.duplicates.items():
            # 创建组项
            group_item = QTreeWidgetItem([f"重复组 {group_id}", "", ""])
            group_item.setFlags(group_item.flags() | Qt.ItemIsUserCheckable)
            group_item.setCheckState(0, Qt.Unchecked)
            # 为组项设置不同的背景色
            if group_id % 2 == 0:
                group_item.setBackground(0, QColor("#f0f7ff"))
                group_item.setBackground(1, QColor("#f0f7ff"))
                group_item.setBackground(2, QColor("#f0f7ff"))

            for path in paths:
                # 获取文件大小
                try:
                    file_size = os.path.getsize(path)
                    size_str = self.format_file_size(file_size)
                except:
                    size_str = "未知"

                # 创建文件项
                file_item = QTreeWidgetItem(["", path, size_str])
                file_item.setFlags(file_item.flags() | Qt.ItemIsUserCheckable)
                file_item.setCheckState(0, Qt.Unchecked)
                group_item.addChild(file_item)

            self.duplicates_tree.addTopLevelItem(group_item)
            # 默认展开组
            self.duplicates_tree.expandItem(group_item)

    def format_file_size(self, size_bytes):
        """将字节大小格式化为人类可读的形式"""
        for unit in ['B', 'KB', 'MB', 'GB']:
            if size_bytes < 1024.0:
                return f"{size_bytes:.2f} {unit}"
            size_bytes /= 1024.0
        return f"{size_bytes:.2f} TB"

    def on_item_selected(self):
        """处理项目选择事件，显示预览"""
        selected_items = self.duplicates_tree.selectedItems()
        if not selected_items:
            return

        # 获取选中的图片路径
        image_paths = []
        for item in selected_items:
            # 如果是顶层项（组），则获取所有子项的路径
            if item.parent() is None:
                for i in range(item.childCount()):
                    child = item.child(i)
                    path = child.text(1)
                    if path and os.path.exists(path):
                        image_paths.append(path)
            else:
                # 如果是子项，直接获取路径
                path = item.text(1)
                if path and os.path.exists(path):
                    image_paths.append(path)

        # 显示预览
        self.image_preview.set_image(image_paths)

    def one_click_select(self):
        """一键选择：每组保留一个，选中其余"""
        # 先取消所有选中状态
        self.deselect_all()

        # 遍历所有组
        for i in range(self.duplicates_tree.topLevelItemCount()):
            group_item = self.duplicates_tree.topLevelItem(i)

            # 每组保留第一个，选中其余
            if group_item.childCount() > 1:
                # 选中其余所有
                for j in range(1, group_item.childCount()):
                    file_item = group_item.child(j)
                    file_item.setCheckState(0, Qt.Checked)

        # 提示用户已完成选择
        total_selected, _ = self.count_selected_files()
        QMessageBox.information(
            self, "选择完成",
            f"已自动选择 {total_selected} 个重复图片（每组保留一个）\n"
            "点击'删除选中的图片'按钮可删除这些图片"
        )

    def deselect_all(self):
        """取消所有选中状态"""
        for i in range(self.duplicates_tree.topLevelItemCount()):
            group_item = self.duplicates_tree.topLevelItem(i)
            group_item.setCheckState(0, Qt.Unchecked)

            for j in range(group_item.childCount()):
                file_item = group_item.child(j)
                file_item.setCheckState(0, Qt.Unchecked)

    def count_selected_files(self):
        """统计选中的文件数量"""
        count = 0
        total_size = 0  # 新增：统计总大小
        for i in range(self.duplicates_tree.topLevelItemCount()):
            group_item = self.duplicates_tree.topLevelItem(i)

            for j in range(group_item.childCount()):
                file_item = group_item.child(j)
                if file_item.checkState(0) == Qt.Checked:
                    count += 1
                    # 计算文件大小
                    try:
                        file_path = file_item.text(1)
                        if file_path and os.path.exists(file_path):
                            total_size += os.path.getsize(file_path)
                    except:
                        continue
        return count, total_size

    def delete_selected(self):
        """删除选中的图片"""
        # 收集所有要删除的文件路径和大小
        files_to_delete = []
        total_size = 0

        # 遍历所有组
        for i in range(self.duplicates_tree.topLevelItemCount()):
            group_item = self.duplicates_tree.topLevelItem(i)

            # 检查组内的文件
            for j in range(group_item.childCount()):
                file_item = group_item.child(j)
                if file_item.checkState(0) == Qt.Checked:
                    file_path = file_item.text(1)
                    if file_path and os.path.exists(file_path):
                        files_to_delete.append(file_path)
                        try:
                            total_size += os.path.getsize(file_path)
                        except:
                            continue

        if not files_to_delete:
            QMessageBox.information(self, "提示", "请先选择要删除的图片")
            return

        # 确认删除
        confirm_msg = f"您确定要删除以下 {len(files_to_delete)} 个文件吗？\n"
        confirm_msg += f"总大小: {self.format_file_size(total_size)}\n\n"
        confirm_msg += "\n".join(files_to_delete[:5])  # 只显示前5个文件
        if len(files_to_delete) > 5:
            confirm_msg += f"\n...以及其他 {len(files_to_delete) - 5} 个文件"

        reply = QMessageBox.question(
            self, "确认删除", confirm_msg,
            QMessageBox.Yes | QMessageBox.No, QMessageBox.No
        )

        if reply == QMessageBox.Yes:
            # 执行删除
            deleted_count = 0
            deleted_size = 0
            failed_count = 0
            failed_files = []

            for file_path in files_to_delete:
                try:
                    file_size = os.path.getsize(file_path)
                    os.remove(file_path)
                    deleted_count += 1
                    deleted_size += file_size

                    # 从界面中移除已删除的项目
                    self.remove_file_from_tree(file_path)
                except Exception as e:
                    failed_count += 1
                    failed_files.append(f"{file_path}: {str(e)}")

            # 显示删除结果
            result_msg = f"成功删除 {deleted_count} 个文件\n"
            result_msg += f"清理了 {self.format_file_size(deleted_size)} 的磁盘空间\n"

            if failed_count > 0:
                result_msg += f"\n{failed_count} 个文件删除失败:\n" + "\n".join(failed_files)

            QMessageBox.information(self, "删除完成", result_msg)

            # 更新状态栏
            if self.selected_dirs:
                self.statusBar().showMessage(
                    f"已删除 {deleted_count} 个文件，释放 {self.format_file_size(deleted_size)} 空间 | 目录: {self.selected_dirs[0]}"
                )

            # 清理空的组
            self.clean_empty_groups()

            # 如果所有重复组都被清理，更新按钮状态
            if self.duplicates_tree.topLevelItemCount() == 0:
                self.delete_btn.setEnabled(False)
                self.one_click_select_btn.setEnabled(False)

    def remove_file_from_tree(self, file_path):
        """从树形视图中移除指定文件"""
        for i in range(self.duplicates_tree.topLevelItemCount()):
            group_item = self.duplicates_tree.topLevelItem(i)

            for j in range(group_item.childCount()):
                file_item = group_item.child(j)
                if file_item.text(1) == file_path:
                    group_item.removeChild(file_item)
                    return

    def clean_empty_groups(self):
        """清理空的组"""
        i = 0
        while i < self.duplicates_tree.topLevelItemCount():
            group_item = self.duplicates_tree.topLevelItem(i)
            if group_item.childCount() == 0:
                self.duplicates_tree.takeTopLevelItem(i)
            else:
                i += 1

    def show_about_dialog(self):
        """显示关于对话框"""
        about_text = """
MIT协议，传播随意，任君使用。
用时细心，如果用错，概不负责。

算法简介：
先按文件大小分组，筛选出大小相同的候选文件；
再对候选文件计算 MD5 哈希值，通过哈希值完全确认内容是否完全一致。
利用多线程后台扫描提升效率。
通过树形结构展示重复文件组，支持一键选择冗余文件并删除。
开源地址：https://gitee.com/superlei/bjalexqq8482322
"""
        QMessageBox.about(self, "关于", about_text)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    # 设置全局字体，确保中文显示正常
    font = QFont()
    font.setFamily("SimHei")
    app.setFont(font)
    window = DuplicateImageFinder()
    window.show()
    sys.exit(app.exec_())
